{
	UCE - cross-platform game engine written in delphi.
	Copyright (c) 2009, Shutko Vitaly

	This file is part of UCE.

	UCE is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2.1 of the License, or (at your option) any later version.

	UCE is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
}

unit uMat;

interface

uses
  uTyp;

const
  MAT_PI = 3.1415926535897932384626433832795;
  MAT_RAD = 0.017453292519943295769236907684886; //DegToRad
  MAT_DEG = 57.295779513082320876798154814105; //RadToDeg

type
  TVec = object
    x, y: Single;

    procedure Set_(nx, ny: Single); inline;
    function Add(v: TVec): TVec; inline;
    function Sub(v: TVec): TVec; inline;
    function Mul(s: Single): TVec; inline;
    function Div_(s: Single): TVec; inline;
    function Dot(v: TVec): Single; inline;
    function Perp: TVec; inline;
    function PerpDot(v: TVec): Single; inline;
    function Neg: TVec; inline;
    function Len: Single; inline;
    function Norm: TVec; inline;
  end;

  TVecs = array of TVec;

function MakeVec(x: Single = 0; y: Single = 0): TVec;

implementation

function MakeVec(x: Single = 0; y: Single = 0): TVec;
begin
  Result.x := x;
  Result.y := y;
end;

procedure TVec.Set_(nx, ny: Single);
begin
  x := nx;
  y := ny;
end;

function TVec.Add(v: TVec): TVec;
begin
  Result := MakeVec(
    x + v.x,
    y + v.y);
end;

function TVec.Sub(v: TVec): TVec;
begin
  Result := MakeVec(
    x - v.x,
    y - v.y);
end;

function TVec.Mul(s: Single): TVec;
begin
  Result := MakeVec(
    x * s,
    y * s);
end;

function TVec.Div_(s: Single): TVec;
begin
  Result := MakeVec(
    x / s,
    y / s);
end;

function TVec.Dot(v: TVec): Single;
begin
  Result := x * v.x + y * v.y;
end;

function TVec.Perp: TVec;
begin
  Result := MakeVec(
    -y,
    x);
end;

function TVec.PerpDot(v: TVec): Single;
begin
  Result := x * v.y - y * v.x;
end;

function TVec.Neg: TVec;
begin
  Result := MakeVec(
    -x,
    -y);
end;

function TVec.Len: Single;
begin
  Result := Sqrt(x * x + y * y);
end;

function TVec.Norm: TVec;
var
  invLen: Single;
begin
  invLen := 1 / Len;
  
  Result := MakeVec(
    x * invLen,
    y * invLen);
end;

end.